package stef.home.arp.labos3;

import java.awt.EventQueue;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import javax.swing.JLabel;
import javax.swing.JTextField;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.RenderingHints;

import javax.swing.JButton;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

import stef.home.arp.labos1.matrix.Matrix;
import stef.home.arp.labos1.utils.Utils;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;

public class GUI {

	private JFrame frame;
	private JTextField txtAtxt;
	private JTextField txtBtxt;
	private JTextField txtXtxt;
	private JTextField txtT;
	private JTextField txtTint;
	private JTextField txtPrintt;
	private Matrix[] rk;
	private Matrix[] trapez;
	private DrawPanel drawPanel;
	
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					GUI window = new GUI();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public GUI() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frame = new JFrame();
		frame.setBounds(100, 100, 967, 646);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		JPanel panel = new JPanel();
		frame.getContentPane().add(panel, BorderLayout.WEST);
		GridBagLayout gbl_panel = new GridBagLayout();
		gbl_panel.columnWidths = new int[]{86, 46, 0};
		gbl_panel.rowHeights = new int[]{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
		gbl_panel.columnWeights = new double[]{0.0, 1.0, Double.MIN_VALUE};
		gbl_panel.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
		panel.setLayout(gbl_panel);
		
		JLabel lblA = new JLabel("A:");
		GridBagConstraints gbc_lblA = new GridBagConstraints();
		gbc_lblA.insets = new Insets(0, 0, 5, 5);
		gbc_lblA.gridx = 0;
		gbc_lblA.gridy = 1;
		panel.add(lblA, gbc_lblA);
		
		txtAtxt = new JTextField();
		txtAtxt.setText("A.txt");
		GridBagConstraints gbc_txtAtxt = new GridBagConstraints();
		gbc_txtAtxt.insets = new Insets(0, 0, 5, 0);
		gbc_txtAtxt.anchor = GridBagConstraints.NORTHWEST;
		gbc_txtAtxt.gridx = 1;
		gbc_txtAtxt.gridy = 1;
		panel.add(txtAtxt, gbc_txtAtxt);
		txtAtxt.setColumns(10);
		
		JLabel lblB = new JLabel("B:");
		GridBagConstraints gbc_lblB = new GridBagConstraints();
		gbc_lblB.insets = new Insets(0, 0, 5, 5);
		gbc_lblB.gridx = 0;
		gbc_lblB.gridy = 2;
		panel.add(lblB, gbc_lblB);
		
		txtBtxt = new JTextField();
		txtBtxt.setText("b.txt");
		GridBagConstraints gbc_txtBtxt = new GridBagConstraints();
		gbc_txtBtxt.insets = new Insets(0, 0, 5, 0);
		gbc_txtBtxt.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtBtxt.gridx = 1;
		gbc_txtBtxt.gridy = 2;
		panel.add(txtBtxt, gbc_txtBtxt);
		txtBtxt.setColumns(10);
		
		JLabel lblPocetniX = new JLabel("pocetni x:");
		GridBagConstraints gbc_lblPocetniX = new GridBagConstraints();
		gbc_lblPocetniX.insets = new Insets(0, 0, 5, 5);
		gbc_lblPocetniX.gridx = 0;
		gbc_lblPocetniX.gridy = 3;
		panel.add(lblPocetniX, gbc_lblPocetniX);
		
		txtXtxt = new JTextField();
		txtXtxt.setText("x.txt");
		GridBagConstraints gbc_txtXtxt = new GridBagConstraints();
		gbc_txtXtxt.insets = new Insets(0, 0, 5, 0);
		gbc_txtXtxt.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtXtxt.gridx = 1;
		gbc_txtXtxt.gridy = 3;
		panel.add(txtXtxt, gbc_txtXtxt);
		txtXtxt.setColumns(10);
		
		JLabel lblKorakIntegracije = new JLabel("korak integracije:");
		GridBagConstraints gbc_lblKorakIntegracije = new GridBagConstraints();
		gbc_lblKorakIntegracije.insets = new Insets(0, 0, 5, 5);
		gbc_lblKorakIntegracije.gridx = 0;
		gbc_lblKorakIntegracije.gridy = 5;
		panel.add(lblKorakIntegracije, gbc_lblKorakIntegracije);
		
		txtT = new JTextField();
		txtT.setText("0.01");
		GridBagConstraints gbc_txtT = new GridBagConstraints();
		gbc_txtT.insets = new Insets(0, 0, 5, 0);
		gbc_txtT.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtT.gridx = 1;
		gbc_txtT.gridy = 5;
		panel.add(txtT, gbc_txtT);
		txtT.setColumns(10);
		
		JLabel lblVremenskiInterval = new JLabel("vremenski interval:");
		GridBagConstraints gbc_lblVremenskiInterval = new GridBagConstraints();
		gbc_lblVremenskiInterval.insets = new Insets(0, 0, 5, 5);
		gbc_lblVremenskiInterval.gridx = 0;
		gbc_lblVremenskiInterval.gridy = 6;
		panel.add(lblVremenskiInterval, gbc_lblVremenskiInterval);
		
		txtTint = new JTextField();
		txtTint.setText("10");
		GridBagConstraints gbc_txtTint = new GridBagConstraints();
		gbc_txtTint.insets = new Insets(0, 0, 5, 0);
		gbc_txtTint.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtTint.gridx = 1;
		gbc_txtTint.gridy = 6;
		panel.add(txtTint, gbc_txtTint);
		txtTint.setColumns(10);
		
		JLabel lblIntervalZaIspisivanje = new JLabel("  interval za ispisivanje: ");
		GridBagConstraints gbc_lblIntervalZaIspisivanje = new GridBagConstraints();
		gbc_lblIntervalZaIspisivanje.insets = new Insets(0, 0, 5, 5);
		gbc_lblIntervalZaIspisivanje.gridx = 0;
		gbc_lblIntervalZaIspisivanje.gridy = 7;
		panel.add(lblIntervalZaIspisivanje, gbc_lblIntervalZaIspisivanje);
		
		txtPrintt = new JTextField();
		txtPrintt.setText("100");
		GridBagConstraints gbc_txtPrintt = new GridBagConstraints();
		gbc_txtPrintt.insets = new Insets(0, 0, 5, 0);
		gbc_txtPrintt.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtPrintt.gridx = 1;
		gbc_txtPrintt.gridy = 7;
		panel.add(txtPrintt, gbc_txtPrintt);
		txtPrintt.setColumns(10);
		
		JButton btnGo = new JButton("Izracunaj");
		btnGo.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				NumericIntegration integration = new NumericIntegration(Utils.createMatrix(txtAtxt.getText()), Utils.createMatrix(txtBtxt.getText()), Utils.createMatrix(txtXtxt.getText()), 
						Float.parseFloat(txtT.getText()), Integer.parseInt(txtTint.getText()), Integer.parseInt(txtPrintt.getText()));
				rk = integration.rungeKutta();
				trapez = integration.trapez();
				drawPanel.repaint();

				}
				
		});
		GridBagConstraints gbc_btnGo = new GridBagConstraints();
		gbc_btnGo.insets = new Insets(0, 0, 0, 5);
		gbc_btnGo.gridx = 0;
		gbc_btnGo.gridy = 10;
		panel.add(btnGo, gbc_btnGo);
		
		drawPanel = new DrawPanel();
		frame.getContentPane().add(drawPanel, BorderLayout.CENTER);
	}

	class DrawPanel extends JPanel{
		
		private static final long serialVersionUID = 5620482285535096545L;
		private final int PAD = 20;
		private double[] data;
		public DrawPanel() {
			setBorder(BorderFactory.createLineBorder(Color.black));
			setBackground(Color.white);
		}
		
		@Override
		protected void paintComponent(Graphics g) {
	        super.paintComponent(g);
	        if(rk!=null){
		        Graphics2D g2 = (Graphics2D)g;
		        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
		                            RenderingHints.VALUE_ANTIALIAS_ON);
		        float T = Float.parseFloat(txtTint.getText());
		        XYSeries series = null;
		        XYSeriesCollection dataset = new XYSeriesCollection();
		        for(int j =0;j<rk[0].getNrows();j++){
		        	series = new XYSeries("x"+(j+1));
		        	double[] data = getRow(j,rk);
		        	for(int i =0;i<data.length;i++)
		        		series.add(normalize(i, 0, data.length, 0, T), data[i]);
		        	dataset.addSeries(series);
		        }   
		       
		        //         Generate the graph
		        JFreeChart chart = ChartFactory.createXYLineChart("Runge-Kuntta", // Title
		                "vrijeme", // x-axis Label
		                "varijable stanja", // y-axis Label
		                dataset, // Dataset
		                PlotOrientation.VERTICAL, // Plot Orientation
		                true, // Show Legend
		                true, // Use tooltips
		                false // Configure chart to generate URLs?
		            );
		        int w = getWidth();
		        int h = getHeight()/2;
		        
		        chart.draw(g2, new Rectangle(new Dimension(w, h)));
		        
		        dataset = new XYSeriesCollection();
		        for(int j =0;j<trapez[0].getNrows();j++){
		        	series = new XYSeries("x"+(j+1));
		        	double[] data = getRow(j,trapez);
		        	for(int i =0;i<data.length;i++)
		        		series.add(normalize(i, 0, data.length, 0, T), data[i]);
		        	dataset.addSeries(series);
		        } 
		        
		        JFreeChart chart1 = ChartFactory.createXYLineChart("trapez", // Title
		                "vrijeme", // x-axis Label
		                "varijable stanja", // y-axis Label
		                dataset, // Dataset
		                PlotOrientation.VERTICAL, // Plot Orientation
		                true, // Show Legend
		                true, // Use tooltips
		                false // Configure chart to generate URLs?
		            );
		        
		        chart1.draw(g2, new Rectangle(0,h,w,h));
	        }
		}
		
		public float normalize(float x, float fromLowerBoundary, float fromUpperBoundary, float toLowerBoundary, float toUpperBoundary){
            return toLowerBoundary + ((x - fromLowerBoundary)*(toUpperBoundary - toLowerBoundary))/(fromUpperBoundary-fromLowerBoundary);
		}
		
		private double[] getRow(int row, Matrix[] x){
			double[] data = new double[x.length];
			for(int i=0;i<x.length;i++)
				data[i] = x[i].getMatrix()[row][0];
			return data;
		}
	}
}
